﻿using System;
using System.Text;
using Wp7Tools.Util;

namespace Wp7Tools.Services.Cache {
	public class CachedWebClientService : ICachedWebClientService {
		private IWebClientService _parent;
		private ILocalCache _cache;

		public CachedWebClientService(IWebClientService parent, ILocalCache cache) {
			_parent = parent;
			_cache = cache;
		}

		public void DownloadAsync(Uri uri, Action<string> cacheHit, Action<string> actionOk, Action<Exception> actionError) {
			string key = UriHelper.ToFilename(uri);
			string cached = GetFromCache(key);
			if (cached != null) {
				cacheHit.Invoke(cached);
			}
			BusyService.IncreaseBusyCounter();
			_parent.DownloadAsync(uri, r => OnActionOk(uri, r, actionOk), r => OnActionError(r, actionError));
		}

		private void OnActionOk(Uri uri, string response, Action<string> originalAction) {
			BusyService.DecreaseBusyCounter();
			string key = UriHelper.ToFilename(uri);
			AddToCache(key, response);
			originalAction.Invoke(response);
		}

		private void OnActionError(Exception exception, Action<Exception> originalErrorAction) {
			BusyService.DecreaseBusyCounter();
			originalErrorAction.Invoke(exception);
		}

		private string GetFromCache(string key) {
			return ToString(_cache.GetFromCache(key));
		}

		private void AddToCache(string key, string content) {
			_cache.SaveToCache(key, ToBytes(content));
		}

		private static string ToString(byte[] bytes) {
			return bytes == null ? null : Encoding.UTF8.GetString(bytes, 0, bytes.Length);
		}

		private static byte[] ToBytes(string value) {
			return value == null ? null : Encoding.UTF8.GetBytes(value);
		}
	}
}
